/**
 * @file Frame.h
 * @author Lost
 * @date 五月 2018
 * @brief 
 * 框架
 */

#ifndef __FRAME_H__
#define __FRAME_H__

#include "FrameData.h"
#include "Singleton.h"
#include "Snake.h"

#include <vector>

using namespace std;
/**
 * @brief 策略基类
 */
class CBaseStrategy
{
public:
    /**
     * @brief 获取方向
     */
    virtual EDirType GetDir() = 0;
};

/**
 * @brief 框架类
 */
class CFrame :public CSingleton<CFrame>
{
public:
    CFrame();
    ~CFrame();

public:
    /**
     * @brief 初始化
     */
    bool Init(CBaseStrategy *pStrategy);

    /**
     * @brief 运行框架
     */
    int Run();

    /**
     * @brief 添加蛇
     */
    void AddSnake(CSnake *pSnake);

    /**
    * @brief 判断两点是否是相邻的
    */
    bool IsNear(const Pos &stSrcPos, const Pos &stDirPos);
public:
    /**
     * @brief 获取地图横坐标偏移
     */
    inline int GetMapOffsetX()const { return m_FrameData.stMap.iOffsetX; }

    /**
     * @brief 获取地图纵坐标偏移
     */
    inline int GetMapOffsetY()const { return m_FrameData.stMap.iOffsetY; }

    /**
     * @brief 获取地图宽度
     */
    inline int GetMapWidth()const { return m_FrameData.stMap.iWidth; }

    /**
     * @brief 获取地图高度
     */
    inline int GetMapHight()const { return m_FrameData.stMap.iHight; }

    /**
     * @brief 获取地图数据
     */
    inline const MapData &GetMapData()const { return m_FrameData.stMap; }
   
    /**
     * @brief 获取地图单元格数据
     */
    inline const MapUnitData &GetMapUnitData(int iX, int iY)const { return m_FrameData.stMap.stUnitData[iX][iY]; }

    /**
     * @brief 修改地图单元格数据
     */
    inline MapUnitData &MutableMapUnitData(int iX, int iY) { return m_FrameData.stMap.stUnitData[iX][iY]; }

    /**
     * @brief 获取蛇头位置
     */
    inline const Pos &GetSnakeHead()const { return m_FrameData.stSnake.stBody[0]; }

    /**
     * @brief 获取蛇尾位置
     */
    inline const Pos &GetSnakeTail()const { return m_FrameData.stSnake.stBody[m_FrameData.stSnake.iLength - 1]; }

    /**
     * @brief 获取蛇位置
     */
    inline const Pos *GetSnake()const { return m_FrameData.stSnake.stBody; }

    /**
     * @brief 修改蛇位置
     */
    inline Pos *MutableSnake() { return m_FrameData.stSnake.stBody; }

    /**
     * @brief 获取蛇长度
     */
    inline int GetSnakeLength()const { return m_FrameData.stSnake.iLength; }

    /**
     * @brief 增加蛇长度
     */
    inline void IncreaseSnakeLength() { ++m_FrameData.stSnake.iLength; }
public:
    /**
     * @brief 设置光标位置
     */
    void SetPosition(int x, int y);

    /**
    * @brief 绘制界面
    */
    void Print(const char *csString);
private:
    /**
     * @brief 绘制界面
     */
    void CreateInterface();


    /**
     * @brief 随机创建一个食物
     */
    bool CreateOneFoodRand();


    /**
     * @brief 刷新蛇
     */
    EMapUnitType MoveSnake(EDirType eDir, CSnake &cSnake);
private:
    /*!< 框架数据 */
    FrameData m_FrameData;

    /*!< 策略 */
    CBaseStrategy *m_pStrategy;

    /*!< 蛇 */
    vector<CSnake *> m_vecpSnake;
};



#endif 